package com.icecloud.cloud.filestore.service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import javax.servlet.ServletContext;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.WebUtils;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSFile;
import com.mongodb.gridfs.GridFSInputFile;

@Service
@EnableConfigurationProperties(MongoDBDataSourceProperties.class)
public class FileStoreService {

	private static MongoClient mongoClient = null;

	private static DB db;

	@Autowired
	private ServletContext servletContext;

	@Autowired
	protected FileRepository fileRepository;

	@Autowired
	protected MongoDBDataSourceProperties mongoDBDataSourceProperties;
	@Autowired
	private TokenStore tokenStore;

	@Autowired
	private ClientDetailsService clientDetailsService;

	/**
	 * 2中连接方式
	 * 上面为有账号密码
	 * 下面为无密码
	 * @return
	 */
	@Bean(destroyMethod = "close")
	public MongoClient MongoClient() {
		try {
			MongoCredential credential = MongoCredential.createCredential(mongoDBDataSourceProperties.getUsername(),
					mongoDBDataSourceProperties.getDatabase(), mongoDBDataSourceProperties.getPassword().toCharArray());
			mongoClient = new MongoClient(
					new ServerAddress(mongoDBDataSourceProperties.getUrl(), mongoDBDataSourceProperties.getPort()),
					Arrays.asList(credential));
//			mongoClient = new MongoClient("192.168.1.98", 27300);
			db = mongoClient.getDB("filestores");
			return mongoClient;
		} catch (UnknownHostException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 保存文件 根据当前token获取当前用户所在公司id后进行保存
	 * 
	 * @param filename
	 * @param contentType
	 * @param file
	 * @throws IOException
	 */
	public String saveFile(String access_token, String filename, String contentType, MultipartFile file)
			throws IOException {
		String companyId = getCompanyIdByAccessToken(access_token);
		GridFS gfs = new GridFS(db);
		GridFSInputFile gfsFile = gfs.createFile(new File(WebUtils.getRealPath(servletContext, storeByExt(companyId,
				FilenameUtils.getExtension(file.getOriginalFilename()).toLowerCase(Locale.ENGLISH), file))));
		gfsFile.setFilename(filename);
		gfsFile.setContentType(contentType);
		DBObject metadata = new BasicDBObject();
		metadata.put("companyId", companyId);
		gfsFile.setMetaData(metadata);
		gfsFile.save();
		return gfsFile.getId().toString();
	}

	private String getCompanyIdByAccessToken(String access_token) {
		OAuth2Authentication result = tokenStore.readAuthentication(access_token);
		ClientDetails clientDetails = clientDetailsService.loadClientByClientId(result.getOAuth2Request().getClientId());
		String companyId= null;
		if(clientDetails != null && clientDetails.getAdditionalInformation() !=null){
			try {
				companyId = clientDetails.getAdditionalInformation().get("additionalInformation").toString();
			} catch (Exception e) {
				// 当查询不到数据时返回null
				return companyId;
			}
		}
		return companyId;
	}

	/**
	 * 读取文件
	 * 
	 * @param filename
	 * @return
	 */
	public InputStream getFileByFilename(String filename) {
		InputStream result = null;
		try {
			GridFS gfs = new GridFS(db);
			GridFSDBFile r = gfs.findOne(filename);
			result = r.getInputStream();
		} catch (Exception e) {
		}
		return result;
	}

	/**
	 * 读取文件
	 * 
	 * @param objectId
	 * @return
	 */
	public GridFSDBFile getFileById(String id) {
		try {
			GridFS gfs = new GridFS(db);
			return gfs.find(new ObjectId(id));
		} catch (Exception e) {
		}
		return null;
	}

	/**
	 * 读取文件列表
	 * 
	 * @param companyId
	 *            查询对应公司id的所以文件
	 * @return
	 */
	public List<GridFSDBFile> getFileList(String access_token) {
		try {
			GridFS gfs = new GridFS(db);
			final DBObject query = new BasicDBObject();;
			String companyId = getCompanyIdByAccessToken(access_token);
			if(StringUtils.isNotEmpty(companyId)){
				query.put("metadata.companyId", companyId);
			}
			return gfs.find(query);
		} catch (Exception e) {
		}
		return null;
	}

	protected String storeByExt(String companyId, String ext, MultipartFile file) throws IOException {
		StringBuffer sb = new StringBuffer();
		sb.append("file").append(File.separator).append(companyId);
		return fileRepository.storeByExt(sb.toString(), ext, file);

	}

}
